/*************** Raising and catching ***************/
#define NSExceptionBase 100000 // TEMPORARY!
#define NSLastException 100999 // TEMPORARY!
// Private definition
typedef struct _NSHandler { /* a node in the handler chain */
jmp_buf jumpState; /* place to longjmp to */
struct _NSHandler *next; /* ptr to next handler */
int code; /* error code of exception; always >=NSExceptionBase and <=NSLastException for now */
const void *data1; /* The exception object */
const void *data2; /* Reserved for compatibility */
} NSHandler;
/* NS_DURING, NS_HANDLER and NS_ENDHANDLER are always used like:
NS_DURING
some code which might raise an error
NS_HANDLER
code that will be jumped to if an error occurs
NS_ENDHANDLER
If any error is raised within the first block of code, the second block of code will be jumped to. Typically, this code will clean up any resources allocated in the routine, possibly case on the error code and perform special processing, and default to -raise again the exception to the next handler. Within the scope of the handler, a local variable called 'exception' holds the raised exception.
It is illegal to exit the first block of code by any other means than
NS_VALRETURN, NS_VOIDRETURN, or just falling out the bottom.
*/
/* private support routines. Do not call directly. */
#define NS_VALRETURN(val) do { typeof(val) temp = (val); \
_NSRemoveHandler(&_localHandler); \
return(temp); } while (0)
#define NS_VOIDRETURN do { _NSRemoveHandler(&_localHandler); \
return; } while (0)
/*************** Changing the top level error catcher ***********/
/* The top level error catcher can be set to look for certain exceptions, do some work, and then either abort or call the previous top level error catcher */
/*********** Assertion of program consistency ***********/
/* Assertions evaluate a condition, and if it is false, they call the NSAssertionHandler for the current thread to report that fact. The assertion macros also take a "description" argument, which should describe the failure that is being tested for. The description is a printf-style format NSString. N args may be passed using the NSAssertN() variations. When calling from within a method, the object's class and method name need not be included in the description, since those args are passed separately.
Assertions are compiled into code if the cpp macro NS_BLOCK_ASSERTIONS is defined. Runtime control is achieved by substituting a different assertion handler.
Since these macros pass the variables "self" and "_cmd" automatically, they assume that they are being called from within a method context. There is a parallel set of macros for use within C functions.